<?php

namespace app\api\model\student;

use app\api\model\job\Job;
use app\api\model\question\Questionnaire;
use app\api\model\question\Topic;
use app\api\model\Setting as SettingModel;
use app\api\service\User as UserService;
use app\common\model\student\Sign as Model;
use think\db\exception\DbException;
use think\Paginator;

class Sign extends Model
{
    protected $append = ['job_level_text', 'job_name'];

    public function getJobNameAttr($value, $data)
    {
        $job = Job::detail($data['job_id']);
        return $job ? $job->job_name : '';
    }

    /**
     * 待考试列表
     * @param array $student_user_id
     * @throws DbException
     */
    public function getList($student_user_id, $study = 0)
    {
        // 查询模型
        $query = $this->getNewQuery();
        // 查询列表记录
        $query = $query
            ->field('student_sign_id,job_id,job_level,status,questionnaire_id,learning_duration')
            ->where('student_user_id', '=', $student_user_id)
            ->where('is_delete', '=', '0')
//            ->where('status', '=', '0')
            ->order(['student_sign_id' => 'desc']);
//        if ($study) {
//            $query->group('');
//        }

        $list = $query->select();
        $learning_duration = 0;
        foreach ($list as $item) {
            //将分钟转成秒
            $item->learning_duration = $item->learning_duration * 60;
            $learning_duration += $item->learning_duration;

            $questionnaire = Questionnaire::detail($item->questionnaire_id);
            $item->answering_time = $questionnaire->answering_time;
            $item->passScore = $questionnaire->passing_mark;
//            $item->totalQuestions = (new Topic)->where(['is_delete' => 0, 'questionnaire_id' => $item->questionnaire_id])->count();
            $item->totalQuestions = 50;
        }
        return ['list' => $list, 'learning_duration' => $learning_duration];
    }

    public function saveSignImg($data)
    {
        return $this->where(['student_sign_id' => $data['student_sign_id']])->save(['promise_sign_base' => $data['promise_sign_base']]);
    }

    public function saveFaceImg($data, $user)
    {
        $values = SettingModel::getItem('examination');
        if (!empty($values['is_face']) && $values['is_face'] == 2) {
//            var_dump($user->full_name);
//            var_dump($user->id_card);
            throwError('验证失败，人脸验证未生效，请联系管理员');
        }
        $this->where(['student_sign_id' => $data['student_sign_id']])->save(['face_base' => $data['face_base']]);
        return true;
    }

    public function handInAPaper($data)
    {
        $student_sign_id = $data['student_sign_id'];
        $sheet_sign_base = $data['sheet_sign_base'];
        $answer = $data['answer'];

        $sign = $this
            ->field('student_sign_id,job_id,job_level,questionnaire_id,status')
            ->where([
                'student_sign_id' => $student_sign_id,
                'is_delete' => 0
            ])->find();
        if (!$sign) {
            $this->error = "学员信息不存在!";
            return false;
        }

        $sheet_title = $sign->job_name . $sign->job_level_text . '考试';

        $questionnaire_info = (new Questionnaire())
            ->field('questionnaire_id,answering_time,passing_mark')
            ->where([
                'questionnaire_id' => $sign->questionnaire_id,
                'is_delete' => 0,
                'status' => 0
            ])
            ->find();
        if (!$questionnaire_info) {
            $this->error = "未找到指定问卷信息!";
            return false;
        }

        //配置信息
        $config = SettingModel::getItem('examination');

        self::startTrans();
        try {
            $answerSheetModel = new AnswerSheet;
            $answerSheetModel->save([
                'title' => $sheet_title,
                'score' => 0,
                'questionnaire_id' => $sign->questionnaire_id,
                'passing_mark' => $questionnaire_info->passing_mark,
                'answering_time' => $questionnaire_info->answering_time,
                'student_sign_id' => $student_sign_id,
                'sheet_sign_base' => $sheet_sign_base,
                'store_id' => self::$storeId,
                'create_time' => time(),
            ]);

            //得分
            $fractionTotal = 0;
            //总分
            $total_score = 0;

            $save_data = [];
            foreach ($answer as $item) {

                $topic = (new Topic)->where([
                    'topic_id' => $item['topic_id'],
                    'is_delete' => 0,
                ])->field('correct_answer,fraction')->find();
                if (!$topic) {
                    continue;
                }

                $total_score += $topic->fraction;

                $selected = implode(',', $item['selected']);
                $correct_answer = implode(',', $topic->correct_answer);

                if ($selected === $correct_answer) {
                    $fractionTotal += $topic->fraction;
                    $item['is_correct'] = 1;
                } else {
                    $item['is_correct'] = 0;
                }
                $item['answer_sheet_id'] = $answerSheetModel->answer_sheet_id;
                $item['selected'] = $selected;
                $item['correct_answer'] = $correct_answer;
                $item['items'] = json_encode($item['items'], 320);
                $item['fraction'] = $topic->fraction;
                $item['create_time'] = time();
                $item['store_id'] = self::$storeId;

                unset($item['topic_id']);
                $save_data[] = $item;
            }


            if ($fractionTotal >= $questionnaire_info->passing_mark) {
                $sign->status = 1;
            } else {
                // 考试次数及格策略
                if ($config && !empty($config['exam_frequency'])) {
                    if ($config['exam_frequency'] == 1) {
                        //一次
                        $res = $this->sendPassingScore($answer, $questionnaire_info->passing_mark, $total_score, $answerSheetModel->answer_sheet_id);
                        $fractionTotal = $res['fractionTotal'];
                        $save_data = $res['save_data'];
                        $sign->status = 1;
                    } else if ($config['exam_frequency'] == 2) {
                        //二次
                        if ($sign->status > 0) {//状态只要不是待考试，就都是已考过试
                            $res = $this->sendPassingScore($answer, $questionnaire_info->passing_mark, $total_score, $answerSheetModel->answer_sheet_id);
                            $fractionTotal = $res['fractionTotal'];
                            $save_data = $res['save_data'];
                            $sign->status = 1;
                        } else {
                            $sign->status = 2;
                        }
                    }
                } else {
                    $sign->status = 2;
                }
            }

            $sign->save();
            (new AnswerSheetTopic())->insertAll($save_data);
            $answerSheetModel->score = $fractionTotal;
            $answerSheetModel->save();
            // 提交事务
            self::commit();
        } catch (\Exception $e) {
            // 回滚事务
            self::rollback();
            $this->error = $e->getMessage();
            return false;
        }

        return $answerSheetModel->answer_sheet_id;
    }

    public function sendPassingScore($answer, $passing_markm, $total_score, $answer_sheet_id)
    {
        $score = rand($passing_markm, $total_score);
        $correct_count = ceil($score / 2);
        $correct_keys = array_rand($answer, $correct_count);
        $fractionTotal = 0;
        $save_data = [];
        foreach ($answer as $index => $item) {
            $topic = (new Topic)->where([
                'topic_id' => $item['topic_id'],
                'is_delete' => 0,
            ])->field('correct_answer,fraction')->find();
            if (!$topic) {
                continue;
            }
            $correct_answer = implode(',', $topic->correct_answer);
            if (in_array($index, $correct_keys)) {
                $item['is_correct'] = 1;
                $item['selected'] = $correct_answer;
                $fractionTotal += $topic->fraction;
            } else {
                $item['is_correct'] = 0;
                $options = ['A', 'B', 'C', 'D'];
                if ($item['topic_type'] == 1) {
                    $item['selected'] = $this->getMakeWrongAnswer($options, $correct_answer);
                } else {
                    $asf = array_diff($options, [$correct_answer]);
                    $item['selected'] = $asf[array_rand($asf)];
                }
            }
            $item['answer_sheet_id'] = $answer_sheet_id;
            $item['correct_answer'] = $correct_answer;
            $item['items'] = json_encode($item['items'], 320);
            $item['fraction'] = $topic->fraction;
            $item['create_time'] = time();
            $item['store_id'] = self::$storeId;

            unset($item['topic_id']);
            $save_data[] = $item;
        }
        return compact('fractionTotal', 'save_data');
    }

    /**
     * 获取随机组合错误答案
     * @param array $options 题目选项
     * @param string $correctAnswer 正确答案
     * @return string
     */
    public function getMakeWrongAnswer($options, $correctAnswer): string
    {
        //选择必须至少选择两项，否则视为未选
        if (count($options) > 2) {
            $wrongList = [];
            $randWrongList = array_rand($options, rand(2, count($options) - 1));
            foreach ($randWrongList as $index) {
                $wrongList[] = $options[$index];
            }
            $wrongItem = implode(',', $wrongList);

            //如果生成为正确答案，则重新生成
            if ($wrongItem == $correctAnswer) {
                $wrongItem = $this->getMakeWrongAnswer($options, $correctAnswer);
            }
        } else {
            $wrongItem = '';
        }
        return $wrongItem;
    }


    public function subStudyTime()
    {
        $this->learning_duration = $this->learning_duration + 1;
        $this->save();
        return true;
    }
}
